package org.fordprefect.struts2lightboxplugin.components;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.util.ValueStack;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.io.*;

import org.apache.struts2.components.TextField;
import org.apache.struts2.components.AbstractRemoteCallUIBean;
import org.apache.struts2.components.UIBean;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.ServletActionContext;
import org.apache.log4j.Logger;
import org.fordprefect.struts2lightboxplugin.util.ImageUtil;
import org.fordprefect.struts2lightboxplugin.util.FileUtil;

/**
 *
 */
@StrutsTag(name = "thumbnail", tldTagClass = "org.apache.struts2.views.jsp.ui.LightBoxTag", description = "Renders LightBox link")
public class LightBox extends UIBean {

    public static final String TEMPLATE = "lightbox";
    private static Logger log = Logger.getLogger(LightBox.class);

    protected String imageURL;
    protected String imageCaption;
    protected String imageGroup;
    protected Integer thumbnailHeight;
    protected Integer thumbnailWidth;
    protected String thumbnailCssClass;
    protected String thumbnailURL;
    protected String thumbnailDir;
    protected String thumbnailURI;

    public LightBox(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
        super(stack, request, response);
    }

    protected String getDefaultTemplate() {
        return TEMPLATE;
    }

    public void evaluateParams() {
        super.evaluateParams();

        if (imageURL != null) {
            addParameter("imageURL", findString(imageURL));
        }

        if (imageCaption != null) {
            addParameter("imageCaption", findString(imageCaption));
        }

        if (imageGroup != null) {
            addParameter("imageGroup", findString(imageGroup));
        }

        if (thumbnailHeight != null) {
            addParameter("thumbnailHeight", thumbnailHeight);
        }

        if (thumbnailWidth != null) {
            addParameter("thumbnailWidth", thumbnailWidth);
        }

        if (thumbnailCssClass != null) {
            addParameter("thumbnailCssClass", findString(thumbnailCssClass));
        }

        if (thumbnailDir != null) {
            addParameter("thumbnailDir", findString(thumbnailDir));
        }

        if (thumbnailURI != null) {
            addParameter("thumbnailURI", findString(thumbnailURI));
        }

        try {
            log.debug("Request URL: " + ServletActionContext.getRequest().getRequestURL());
            log.debug("Request URI: " + ServletActionContext.getRequest().getRequestURI());
            log.debug("Context Path: " + ServletActionContext.getRequest().getContextPath());
            log.debug("Servlet Path: " + ServletActionContext.getRequest().getServletPath());
            log.debug("Context Name: " + ServletActionContext.getServletContext().getServletContextName());
            log.debug("Context RealPath: " + ServletActionContext.getServletContext().getRealPath("/"));
            log.debug("Context RealPath for Servlet Path: " + ServletActionContext.getServletContext().getRealPath(ServletActionContext.getRequest().getServletPath()));
            generateThumbnail();
            addParameter("thumbnailURL", thumbnailURL);
        } catch (Throwable e) {
            log.error("Error creating thumbnail: " + e.getMessage(), e);
        }


    }

    private void generateThumbnail() throws Exception {
        if (thumbnailWidth == null) {
            thumbnailWidth = 160;
        }
        if (thumbnailHeight == null) {
            thumbnailHeight = 120;
        }
        String imageName = FileUtil.extractImageName(imageURL);
        String thumbnailName = FileUtil.formatThumbNailName(imageName, thumbnailWidth, thumbnailHeight);
        String contextPath = ServletActionContext.getRequest().getContextPath();
        String realPath = ServletActionContext.getServletContext().getRealPath(ServletActionContext.getRequest().getServletPath());
        String currentRealPath = FileUtil.getRealPath(realPath);
        String currentRelativeURI = FileUtil.getRelativeURI(contextPath);
        String imageURI = FileUtil.extractImageDirectory(imageURL);
        File imageRealPath = new File(currentRealPath, imageURL);
        StringBuffer thumbNailDirectory = new StringBuffer();
        if (thumbnailDir == null || thumbnailDir.equalsIgnoreCase("")) {
            if (!currentRealPath.equalsIgnoreCase("")) {
                thumbNailDirectory.append(currentRealPath);
                thumbNailDirectory.append(System.getProperty("file.separator"));
            }
            if (!imageURI.equalsIgnoreCase("")) {
                thumbNailDirectory.append(imageURI);
                thumbNailDirectory.append(System.getProperty("file.separator"));
            }
            thumbNailDirectory.append("thumbnails");
        } else {
            log.debug("Overriding thumbnail directory to: " + thumbnailDir);
            thumbNailDirectory.append(thumbnailDir);
        }
        createThumbnailDirectory(new File(thumbNailDirectory.toString()));
        thumbnailURL = thumbNailDirectory + System.getProperty("file.separator") + thumbnailName;
        if (!new File(thumbnailURL).exists()) {
            InputStream inputStream = new BufferedInputStream(new FileInputStream(imageRealPath));
            OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(new File(thumbnailURL)));
            log.debug("Creating thumbnail \"" + thumbnailURL + "\" [" + thumbnailWidth + "x" + thumbnailHeight + "]");
            ImageUtil.scaleImage(imageName, null, inputStream, outputStream, thumbnailWidth, thumbnailHeight);
        } else log.debug("Using cached thumbnail \"" + thumbnailURL + "\"");
        StringBuffer buff = new StringBuffer();
        if (thumbnailURI != null && !thumbnailURI.equalsIgnoreCase("")) {
            log.debug("Overriding thumbnail URI to: " + thumbnailURI);
            buff.append(thumbnailURI);
        } else {
            if (!currentRelativeURI.equalsIgnoreCase("")) {
                buff.append(currentRelativeURI);
                buff.append(System.getProperty("file.separator"));
            }
            if (!imageURI.equalsIgnoreCase("")) {
                buff.append(imageURI);
                buff.append(System.getProperty("file.separator"));
            }
            if (thumbnailDir != null && !thumbnailDir.equalsIgnoreCase("")) {
                buff.append(thumbnailDir);
            } else {
                buff.append("thumbnails");
            }
        }
        buff.append(System.getProperty("file.separator"));
        buff.append(thumbnailName);
        thumbnailURL = buff.toString();
        log.debug("ThumbnailURI: " + thumbnailURL);
    }

    private void createThumbnailDirectory(File thumbnailDirectory) {
        log.debug("Thumbnail directory: " + thumbnailDirectory.toString());
        if(!thumbnailDirectory.exists()) {
            log.debug("Creating directory: " + thumbnailDirectory.toString());
            thumbnailDirectory.mkdir();
        }
    }



    /*private String getThumbnailDirectory() throws IOException {
        File thumbnailDirectory;
        log.debug("Request URL: " + ServletActionContext.getRequest().getRequestURL());
        log.debug("Request URI: " + ServletActionContext.getRequest().getRequestURI());
        log.debug("Context Path: " + ServletActionContext.getRequest().getContextPath());
        log.debug("Servlet Path: " + ServletActionContext.getRequest().getServletPath());
        log.debug("Context Name: " + ServletActionContext.getServletContext().getServletContextName());
        log.debug("Context RealPath: " + ServletActionContext.getServletContext().getRealPath("/"));
        log.debug("Context RealPath for Servlet Path: " + ServletActionContext.getServletContext().getRealPath(ServletActionContext.getRequest().getServletPath()));
        String dir = ServletActionContext.getServletContext().getRealPath(ServletActionContext.getRequest().getServletPath());
        dir = dir.substring(0, dir.lastIndexOf("/"));
        thumbnailDirectory = new File(dir, extractImageDirectory() + System.getProperty("file.separator") + "thumbnails");
        log.debug("Thumbnail directory: " + thumbnailDirectory.toString());
        if(!thumbnailDirectory.exists()) {
            log.debug("Creating directory: " + thumbnailDirectory.toString());
            thumbnailDirectory.mkdir();
        }
        return thumbnailDirectory.toString();
    }*/

    /**
     * URL to the image to display.
     * @s.tagattribute required="true" type="String"
     */
    @StrutsTagAttribute(description = "URL to the image to display.", required = true,  type = "String")
    public void setImageURL(String imageURL) {
        this.imageURL = imageURL;
    }

    /**
     * The image caption to display.
     * @s.tagattribute required="true" type="String"
     */
    @StrutsTagAttribute(description = "The image caption to display.", required = true, type = "String")
    public void setImageCaption(String imageCaption) {
        this.imageCaption = imageCaption;
    }
    /**
     * The image group this image belongs to
     * @param imageGroup
     */
    public void setImageGroup(String imageGroup) {
        this.imageGroup = imageGroup;
    }

    /**
     * The thumbnail height
     * @param thumbnailHeight
     */
    public void setThumbnailHeight(Integer thumbnailHeight) {
        this.thumbnailHeight = thumbnailHeight;
    }

    /**
     * The thumbnail width
     * @param thumbnailWidth
     */
    public void setThumbnailWidth(Integer thumbnailWidth) {
        this.thumbnailWidth = thumbnailWidth;
    }

    /**
     * Style sheet for thumbnail <img> tag.
     * @param thumbnailCssClass
     */
    public void setThumbnailCssClass(String thumbnailCssClass) {
        this.thumbnailCssClass = thumbnailCssClass;
    }

    /**
     * Override the full relative thumbnail directory
     * @param thumbnailDir
     */
    public void setThumbnailDir(String thumbnailDir) {
        this.thumbnailDir = thumbnailDir;
    }

    /**
     * Override the full relative thumbnail URI
     * @param thumbnailURI
     */
    public void setThumbnailURI(String thumbnailURI) {
        this.thumbnailURI = thumbnailURI;
    }
}
